package com.kylin.system.common.security.login;

import com.kylin.common.core.entity.DataEntity;
import com.kylin.common.core.util.ServletUtils;
import com.kylin.common.security.config.LoginProperties;
import com.kylin.common.security.domain.LoginUser;
import com.kylin.common.security.service.handler.LoginHandler;
import com.kylin.common.security.util.SecurityUtils;
import com.kylin.system.entity.SysUser;
import com.kylin.system.service.SysPermissionService;
import com.kylin.system.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Set;

/**
 * 用户名密码登录
 * @author wuhao
 * @version 1.0 - 2022/10/10
 */
@Component
@Slf4j
public class PasswordLoginHandler implements LoginHandler {

    @Autowired
    private SysUserService userService;
    @Autowired
    private SysPermissionService permissionService;

    // 认证模式
    private static final String GRANT_TYPE = "password";
    // 参数名称
    private static final String PARAM_USERNAME = "username";
    private static final String PARAM_PASSWORD = "password";

    @Override
    public LoginUser handle(HttpServletRequest request) {
        String username = request.getParameter(PARAM_USERNAME);
        String password = request.getParameter(PARAM_PASSWORD);
        // 认证处理..... 成功返回用户,其他抛出异常
        SysUser user = userService.selectUserByUserName(username);
        if(user == null) {
            throw new UsernameNotFoundException("user not found");
        }

        // todo 密码校验
        boolean checkPassword = SecurityUtils.matchesPassword(password, user.getPassword());
        if(!checkPassword) {
            throw new BadCredentialsException("密码错误");
        }

        Set<String> roles = permissionService.getRolePermission(user.getId());
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user.getId());

        LoginUser loginUser = new LoginUser(user.getId(),user.getUserName(),user.getPassword());
        loginUser.setNickName(user.getNickName());
        loginUser.setPhone(user.getPhone());
        loginUser.setDeptId(user.getDeptId());
        loginUser.setPermissions(permissions);
        loginUser.setRoles(roles);
        loginUser.setEnable(DataEntity.STATUS_NORMAL.equalsIgnoreCase(user.getStatus()));

        return loginUser;
    }
    
    /**
     * 是否支持该授权模式处理
     * @param grantType 授权模式
     * @return
     * @author wuhao
     * @since 2.6.0 - 2022/10/10
     */
    @Override
    public boolean supports(String grantType) {
        return GRANT_TYPE.equalsIgnoreCase(grantType);
    }

    @Override
    public String getGrantType() {
        return GRANT_TYPE;
    }

    @Override
    public LoginProperties getLoginProperties() {
        LoginProperties loginProperties = new LoginProperties();
        loginProperties.setEnableCaptcha(true);
        // 7天
        loginProperties.setExpireTimes(7 * 24 * 60 * 60L);
        // 30天
        loginProperties.setRefreshTokenTimes(30 * 24 * 60 * 60L);

        return loginProperties;
    }
}
